
import numpy as np  # 引入numpy
from scipy.optimize import leastsq  # 引入最小二乘函数


class LeastSq:
    def __init__(self, dataset, args):
        self.dataset = dataset
        self.n = 9

    # 目标函数
    def real_func(self, x):
        return np.sin(2 * np.pi * x)

    # 多项式函数
    def fit_func(self, p, x):
        f = np.poly1d(p)
        return f(x)

    # 残差函数
    def residuals_func(self, p, y, x):
        ret = self.fit_func(p, x) - y
        return ret

    def run(self):
        with open(self.dataset, 'r') as f:
            data = f.readline().strip()
            data_row = list(map(float, data.split(" ")))

        x = np.array(data_row)
        x_points = np.linspace(0, 1, 1000)  # 画图时需要的连续点

        y0 = self.real_func(x)  # 目标函数
        y1 = [np.random.normal(0, 0.1) + y for y in y0]  # 添加正太分布噪声后的函数

        p_init = np.random.randn(self.n)  # 随机初始化多项式参数

        plsq = leastsq(self.residuals_func, p_init, args=(y1, x))


        return {
            'Truth': [round(x, 4) for x in self.real_func(x_points)],
            'Predict': [round(x, 4) for x in self.fit_func(plsq[0], x_points)],
            'Description': '本算法为最小二乘回归算法，使用UCI数据集进行验证，后续可以考虑使用食品数据进行拟合预警风险'
        }


if __name__ == '__main__':
    print(LeastSq('../../data/dataset1', {}).run())
